home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / xwindows / demos / xfract_1.z / xfract_1 / xfractint-1.06 / gifview.c < prev    next >
C/C++ Source or Header  |  1992-09-28  |  7KB  |  300 lines

  1. /*
  2.  *
  3.  * This GIF decoder is designed for use with Bert Tyler's FRACTINT
  4.  * program. It should be noted that the "FRACTINT" program only decodes
  5.  * GIF files FRACTINT creates, so this decoder code lacks full generality
  6.  * in the following respects: supports single image, non-interlaced GIF
  7.  * files with no local color maps and no extension blocks.
  8.  *
  9.  * GIF and 'Graphics Interchange Format' are trademarks (tm) of
  10.  * Compuserve, Incorporated, an H&R Block Company.
  11.  *
  12.  *                                            Tim Wegner
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #ifndef XFRACT
  18. #include <dos.h>
  19. #endif
  20. #include "fractint.h"
  21. #include "prototyp.h"
  22.  
  23. static void close_file(void);
  24.  
  25. #define MAXCOLORS    256
  26.  
  27. extern int rowcount;        /* row counter for screen */
  28. extern char readname[];     /* file name          */
  29. static FILE *fpin = NULL;    /* FILE pointer       */
  30. unsigned int height;
  31. extern    char busy;
  32. unsigned numcolors;
  33.  
  34. extern char MAP_name[];
  35. extern int mapset;
  36. extern int colorstate;        /* comments in cmdfiles */
  37.  
  38. extern int colors;
  39. extern int glassestype;
  40. extern int display3d;
  41. extern int dotmode;        /* so we can detect disk-video */
  42. extern int calc_status;
  43. extern long calctime;
  44. extern long timer_interval;
  45. extern int pot16bit;        /* 16 bit values for continuous potential */
  46. extern int dither_flag;
  47.  
  48. extern int (*outln)();
  49. static int out_line_dither(BYTE *, int);
  50.  
  51. int bad_code_count = 0;     /* needed by decoder module */
  52.  
  53. int get_byte()
  54. {
  55.    return (getc(fpin)); /* EOF is -1, as desired */
  56. }
  57.  
  58. int get_bytes(BYTE *where,int how_many)
  59. {
  60.    return (fread((char *)where,1,how_many,fpin)); /* EOF is -1, as desired */
  61. }
  62.  
  63. extern BYTE dacbox[256][3];    /* Video-DAC (filled in by SETVIDEO) */
  64. #ifndef XFRACT
  65. extern BYTE decoderline[MAXPIXELS+1]; /* write-line routines use this */
  66. #else
  67. BYTE decoderline[MAXPIXELS+1]; /* write-line routines use this */
  68. #endif
  69.  
  70. static int ditherlen = -1;
  71. static char far *ditherbuf = NULL;
  72.  
  73. /* Main entry decoder */
  74. int gifview()
  75. {
  76.    BYTE buffer[16];
  77.    unsigned width, finished;
  78.    char temp1[81];
  79.  
  80.    int status;
  81.    int i, j, k, planes;
  82.  
  83.    status = 0;
  84.  
  85.    /* initialize the row count for write-lines */
  86.    rowcount = 0;
  87.  
  88.    /* zero out the full write-line */
  89.    for (width = 0; width < MAXPIXELS+1; width++) decoderline[width] = 0;
  90.  
  91.    /* Open the file */
  92.    strcpy(temp1,readname);
  93.    if (strchr(temp1,'.') == NULL) {
  94.       strcat(temp1,DEFAULTFRACTALTYPE);
  95.       if ((fpin = fopen(temp1,"rb")) != NULL) {
  96.      fclose(fpin);
  97.      }
  98.       else {
  99.      strcpy(temp1,readname);
  100.      strcat(temp1,ALTERNATEFRACTALTYPE);
  101.      }
  102.       }
  103.    if ((fpin = fopen(temp1, "rb")) == NULL)
  104.       return (-1);
  105.  
  106.    /* Get the screen description */
  107.    for (i = 0; i < 13; i++)
  108.    {
  109.       int tmp;
  110.  
  111.       buffer[i] = tmp = get_byte();
  112.       if (tmp < 0)
  113.       {
  114.      close_file();
  115.      return(-1);
  116.       }
  117.    }
  118.  
  119.    if(strncmp(buffer,"GIF87a",3) ||             /* use updated GIF specs */
  120.       buffer[3] < '0' || buffer[3] > '9' ||
  121.       buffer[4] < '0' || buffer[4] > '9' ||
  122.       buffer[5] < 'A' || buffer[5] > 'z' )
  123.    {
  124.       close_file();
  125.       return(-1);
  126.    }
  127.  
  128.    planes = (buffer[10] & 0x0F) + 1;
  129.  
  130.    if((buffer[10] & 0x80)==0)     /* color map (better be!) */
  131.    {
  132.       close_file();
  133.       return(-1);
  134.    }
  135.    numcolors = 1 << planes;
  136.  
  137.    if (dither_flag && numcolors>2 && colors==2 && outln==out_line) {
  138.      outln = out_line_dither;
  139.    }
  140.  
  141.  
  142.    for (i = 0; i < numcolors; i++)
  143.    {
  144.       for (j = 0; j < 3; j++) {
  145.      if ((k = get_byte()) < 0)
  146.      {
  147.         close_file();
  148.         return(-1);
  149.      }
  150.      if(!display3d || (glassestype != 1 && glassestype != 2))
  151.         dacbox[i][j] = k >> 2;
  152.       }
  153.    }
  154.    colorstate = 1; /* colors aren't default and not a known .map file */
  155.  
  156.    /* don't read if glasses */
  157.    if (display3d && mapset && glassestype!=1 && glassestype != 2)
  158.    {
  159.        ValidateLuts(MAP_name);    /* read the palette file */
  160.        spindac(0,1); /* load it, but don't spin */
  161.    }
  162.    if (dacbox[0][0] != 255)
  163.       spindac(0,1);      /* update the DAC */
  164.  
  165.    if (dotmode == 11) /* disk-video */
  166.        dvid_status(1,"...restoring...");
  167.  
  168.    /* Now display one or more GIF objects */
  169.    finished = 0;
  170.    while (!finished)
  171.    {
  172.       switch (get_byte())
  173.       {
  174.       case ';':
  175.      /* End of the GIF dataset */
  176.  
  177.      finished = 1;
  178.      status = 0;
  179.      break;
  180.  
  181.       case '!':                               /* GIF Extension Block */
  182.      get_byte();             /* read (and ignore) the ID */
  183.      while ((i = get_byte()) > 0)     /* get the data length */
  184.         for (j = 0; j < i; j++)
  185.            get_byte();     /* flush the data */
  186.      break;
  187.       case ',':
  188.      /*
  189.       * Start of an image object. Read the image description.
  190.       */
  191.  
  192.      for (i = 0; i < 9; i++)
  193.      {
  194.             int tmp;
  195.  
  196.             buffer[i] = tmp = get_byte();
  197.         if (tmp < 0)
  198.         {
  199.            status = -1;
  200.            break;
  201.         }
  202.      }
  203.      if(status < 0)
  204.      {
  205.         finished = 1;
  206.         break;
  207.      }
  208.  
  209.      width    = buffer[4] | (buffer[5] << 8);
  210.      if (pot16bit) width >>= 1;
  211.      height = buffer[6] | (buffer[7] << 8);
  212.  
  213.          /* Skip local color palette */
  214.          if((buffer[8] & 0x80)==0x80) {      /* local map? */
  215.              int numcolors;    /* make this local */
  216.              planes = (buffer[8] & 0x0F) + 1;
  217.              numcolors = 1 << planes;
  218.              /* skip local map */
  219.              for (i = 0; i < numcolors; i++) {
  220.                 for (j = 0; j < 3; j++) {
  221.                    if ((k = get_byte()) < 0) {
  222.                       close_file();
  223.                       return(-1);
  224.                       }
  225.                    }
  226.                 }
  227.              }
  228.  
  229.      if (calc_status == 1) /* should never be so, but make sure */
  230.         calc_status = 0;
  231.      busy = 1;    /* for slideshow CALCWAIT */
  232.      status = timer(1,NULL,width); /* call decoder(width) via timer */
  233.      busy = 0;    /* for slideshow CALCWAIT */
  234.      if (calc_status == 1) /* e.g., set by line3d */
  235.      {
  236.         calctime = timer_interval; /* note how long it took */
  237.         if (keypressed() != 0)
  238.            calc_status = 3; /* interrupted, not resumable */
  239.         else
  240.            calc_status = 4; /* complete */
  241.      }
  242.      finished = 1;
  243.      break;
  244.       default:
  245.      status = -1;
  246.      finished = 1;
  247.      break;
  248.       }
  249.    }
  250.    close_file();
  251.    if (dotmode == 11) { /* disk-video */
  252.       dvid_status(0,"Restore completed");
  253.       dvid_status(1,"");
  254.       }
  255.       
  256.     if (ditherbuf != NULL) { /* we're done, free dither memory */
  257.         farmemfree(ditherbuf);
  258.         ditherbuf = NULL;
  259.     }
  260.  
  261.    return(status);
  262. }
  263.  
  264. static void close_file()
  265. {
  266.    fclose(fpin);
  267.    fpin = NULL;
  268. }
  269.  
  270. extern int rowcount;
  271.  
  272.  
  273. static int out_line_dither(pixels, linelen)
  274. BYTE *pixels;
  275. int linelen;
  276. {
  277.     int i,nexterr,brt,err;
  278.     if(ditherbuf == NULL)
  279.         ditherbuf = (char far *)farmemalloc(linelen+1);
  280.     far_memset( ditherbuf, 0, linelen+1); 
  281.  
  282.     nexterr = (rand15()&0x1f)-16;
  283.     for (i=0;i<linelen;i++) {
  284.     brt = (dacbox[pixels[i]][0]*5+dacbox[pixels[i]][1]*9 +
  285.         dacbox[pixels[i]][2]*2)>>4; /* brightness from 0 to 63 */
  286.     brt += nexterr;
  287.     if (brt>32) {
  288.         pixels[i] = 1;
  289.         err = brt-63;
  290.     } else {
  291.         pixels[i] = 0;
  292.         err = brt;
  293.     }
  294.     nexterr = ditherbuf[i+1]+err/3;
  295.     ditherbuf[i] = err/3;
  296.     ditherbuf[i+1] = err/3;
  297.     }
  298.     return out_line(pixels, linelen);
  299. }
  300.